/* This file is part of swapper project
 *
 * Copyright (C) 2020 The Swapper Project Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.swapper.json

import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test

class JsonArrayExTest {
  @Test
  fun test_parseBooleanArray() {
    val booleanArray: BooleanArray = booleanArrayOf(
      true, true, true, true, true, false,
      false, false, true, true, true, true,
      true, false, false, true, true, false,
      false, true, true, false, false, true,
      false, true, false, false, true, false,
      true, false
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, booleanArray)

    val booleanArray1: BooleanArray = jsonArray.parseBooleanArray()
    val booleanArray2: BooleanArray = jsonArray.parseBooleanArray(jsonContext)
    val booleanArray3: Array<Boolean> = jsonArray.parseArray()
    val booleanArray4: Array<Boolean> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(booleanArray[i], booleanArray1[i])
      Assertions.assertEquals(booleanArray1[i], booleanArray2[i])
      Assertions.assertEquals(booleanArray2[i], booleanArray3[i])
      Assertions.assertEquals(booleanArray3[i], booleanArray4[i])
    }
  }

  @Test
  fun test_parseCharArray() {
    val charArray: CharArray = charArrayOf(
      'A', 'B', 'C', 'D', 'E', 'F', 'G',
      'H', 'I', 'J', 'K', 'L', 'M', 'N',
      'O', 'P', 'Q', 'R', 'S', 'T', 'U',
      'V', 'W', 'X', 'Y', 'Z',
      'a', 'b', 'c', 'd', 'e', 'f', 'g',
      'h', 'i', 'j', 'k', 'l', 'm', 'n',
      'o', 'p', 'q', 'r', 's', 't', 'u',
      'v', 'w', 'x', 'y', 'z'
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, charArray)

    val charArray1: CharArray = jsonArray.parseCharArray()
    val charArray2: CharArray = jsonArray.parseCharArray(jsonContext)
    val charArray3: Array<Char> = jsonArray.parseArray()
    val charArray4: Array<Char> = jsonArray.parseArray(jsonContext)
    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(charArray[i], charArray1[i])
      Assertions.assertEquals(charArray1[i], charArray2[i])
      Assertions.assertEquals(charArray2[i], charArray3[i])
      Assertions.assertEquals(charArray3[i], charArray4[i])
    }
  }

  @Test
  fun test_parseByteArray() {
    val byteArray: ByteArray = byteArrayOf(
      -59, 6, 33, -97, 100, 50, 82,
      16, 60, -13, -5, -122, 5, -36,
      26, -62, 88, 15, -65, 94, 98,
      -34, -33, 18, -44, -75, 103,
      50, 29, 56, -108, 122
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, byteArray)

    val byteArray1: ByteArray = jsonArray.parseByteArray()
    val byteArray2: ByteArray = jsonArray.parseByteArray(jsonContext)
    val byteArray3: Array<Byte> = jsonArray.parseArray()
    val byteArray4: Array<Byte> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(byteArray[i], byteArray1[i])
      Assertions.assertEquals(byteArray1[i], byteArray2[i])
      Assertions.assertEquals(byteArray2[i], byteArray3[i])
      Assertions.assertEquals(byteArray3[i], byteArray4[i])
    }
  }

  @Test
  fun test_parseShortArray() {
    val shortArray: ShortArray = shortArrayOf(
      -27335, -6513, 2304, -3430, -5955, 25962,
      -16428, 24134, 28617, -20685, -11191,
      -20721, 28212, 5177, 8233, -11711,
      -31070, 24025, 29033, -17373, -32528,
      17753, -2085, 1956, 18746, 10251,
      -7477, -16215, 15805, -1347, 18804, 32286
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, shortArray)

    val shortArray1: ShortArray = jsonArray.parseShortArray()
    val shortArray2: ShortArray = jsonArray.parseShortArray(jsonContext)
    val shortArray3: Array<Short> = jsonArray.parseArray()
    val shortArray4: Array<Short> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(shortArray[i], shortArray1[i])
      Assertions.assertEquals(shortArray1[i], shortArray2[i])
      Assertions.assertEquals(shortArray2[i], shortArray3[i])
      Assertions.assertEquals(shortArray3[i], shortArray4[i])
    }
  }

  @Test
  fun test_parseIntArray() {
    val intArray: IntArray = intArrayOf(
      960292301, -531567831, -911825484, -1075162201, 214681507,
      -985435621, -778598575, -416532332, 1178322371, 140860861,
      1379304505, 486685181, -427264104, 1912554742, 1716766572,
      1951415832, 1711069481, -1096219459, 921672092, 602839514,
      783265342, 266658872, -1995132400, -2011709665, 1281577968,
      -2069367074, -1655084019, 1891757172, 1688395574, 617391435,
      974838948, -1790200685
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, intArray)

    val intArray1: IntArray = jsonArray.parseIntArray()
    val intArray2: IntArray = jsonArray.parseIntArray(jsonContext)

    val intArray3: Array<Int> = jsonArray.parseArray()
    val intArray4: Array<Int> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(intArray[i], intArray1[i])
      Assertions.assertEquals(intArray1[i], intArray2[i])
      Assertions.assertEquals(intArray2[i], intArray3[i])
      Assertions.assertEquals(intArray3[i], intArray4[i])
    }
  }

  @Test
  fun test_parseLongArray() {
    val longArray: LongArray = longArrayOf(
      -227531863481737516, 8610923751484020812, 2457820667828763752,
      1452228788412796027, -1428985983002858267, 1503893747149183273,
      -6418863647708818091, -5217965600067331150, 6147440709786488587,
      9214170411977436777, -2931524235136030639, -1256675116723188825,
      5189779364292957271, -7787657678028182916, -6302126051117708521,
      5154138554116308132, -4994439055198476826, -5449395360078377253,
      3347198136661010983, 1587732456953856610, 195707827261076226,
      5031226885468409794, 2659827474272045049, -988303356412534245,
      6585316125049024794, 3493044993967360764, 7546653419921095226,
      3949772193422437861, 7521186144343458217, 7174735716558394877,
      8947040720730891047, -9139948565879112541
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, longArray)

    val longArray1: LongArray = jsonArray.parseLongArray()
    val longArray2: LongArray = jsonArray.parseLongArray(jsonContext)
    val longArray3: Array<Long> = jsonArray.parseArray()
    val longArray4: Array<Long> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(longArray[i], longArray1[i])
      Assertions.assertEquals(longArray1[i], longArray2[i])
      Assertions.assertEquals(longArray2[i], longArray3[i])
      Assertions.assertEquals(longArray3[i], longArray4[i])
    }
  }

  @Test
  fun test_parseFloatArray() {
    val floatArray: FloatArray = floatArrayOf(
      2.5627488E38F, 1.9779718E38F, 1.9770646E38F, 2.3403935E38F,
      3.0784672E38F, 3.0546041E38F, 2.3711E38F, 9.625589E37F,
      3.0733315E38F, 2.7776024E38F, 8.646818E37F, 1.848682E38F,
      2.9608824E37F, 2.2952593E38F, 2.0276607E38F, 9.214264E37F,
      1.2188968E38F, 1.544956E38F, 1.1378569E38F, 1.422635E38F,
      3.047554E38F, 2.071931E38F, 1.2699028E38F, 1.8697694E38F,
      1.3557974E38F, 3.3478295E38F, 4.4711213E37F, 1.5888591E38F,
      2.6597555E38F, 2.4648853E38F, 1.6073034E38F, 3.843787E37F
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, floatArray)

    val floatArray1: FloatArray = jsonArray.parseFloatArray()
    val floatArray2: FloatArray = jsonArray.parseFloatArray(jsonContext)
    val floatArray3: Array<Float> = jsonArray.parseArray()
    val floatArray4: Array<Float> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(floatArray[i], floatArray1[i])
      Assertions.assertEquals(floatArray1[i], floatArray2[i])
      Assertions.assertEquals(floatArray2[i], floatArray3[i])
      Assertions.assertEquals(floatArray3[i], floatArray4[i])
    }
  }

  @Test
  fun test_parseDoubleArray() {
    val doubleArray: DoubleArray = doubleArrayOf(
      1.531399964947552E308, 5.532464370198205E307, 1.5812586396418351E308,
      1.682062505753334E308, 3.6980738921974265E307, 1.3928636548109374E308,
      9.747827546499428E307, 1.6737228661365711E308, 1.5414825488172194E308,
      7.335419172313477E306, 9.632056060642483E307, 1.7458496717340452E308,
      1.415184114064991E308, 1.2253048443114192E308, 7.782301166511894E307,
      4.60128511120709E307, 4.83280589643758E306, 1.1698371642412228E308,
      1.2106717968109422E308, 1.1256716158948247E308, 1.2673932473274906E308,
      7.450557042435621E307, 1.151028836739692E308, 9.111894642267857E306,
      8.18760492393941E306, 1.1461755166472348E308, 4.867646915659621E307,
      1.1793907230515802E308, 1.2280166353767884E308, 6.639284437851627E307,
      5.884338270249669E307, 5.820845486603443E307
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, doubleArray)

    val doubleArray1: DoubleArray = jsonArray.parseDoubleArray()
    val doubleArray2: DoubleArray = jsonArray.parseDoubleArray(jsonContext)
    val doubleArray3: Array<Double> = jsonArray.parseArray()
    val doubleArray4: Array<Double> = jsonArray.parseArray(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(doubleArray[i], doubleArray1[i], 1e-6)
      Assertions.assertEquals(doubleArray1[i], doubleArray2[i], 1e-6)
      Assertions.assertEquals(doubleArray2[i], doubleArray3[i], 1e-6)
      Assertions.assertEquals(doubleArray3[i], doubleArray4[i], 1e-6)
    }
  }

  @Test
  fun test_parseList_parseMutableList() {
    val stringList: List<String> = listOf(
      "vqzxeevwcboswvzv", "qesigpocbptcesea", "pwpxaqwpxdmkkxsj",
      "tztzsifwbdcqmgbg", "fuwkhpsxclqklsew", "jhbcptnhzajghrqw",
      "eebmykfybtipjyck", "kbudqwucdiluswnx", "tbsxebhvkhhtscah",
      "gpdhgrcvqqyxzkxf", "xdurjnroxxwgqduf", "jyjfkxeautxitlcf",
      "hvnuypfxvqlpbgom", "yckfjwkazxaedsum", "whboaazsbowhwzes",
      "vakxxkwjvvblnfkd", "rmqarppbrescpiig", "xkkwmsyipkyjmdgt",
      "dsmmohrmdmlzovfp", "azivdgcgbkrhtaen", "bjqfwvcnhlkpmwfo",
      "gthwdlnfvihgobin", "olaqpqqmrpyaaokg", "fmgozwfvuscuixad",
      "fufnobbnsnngeura", "pyziwqwewinukjma", "feiiywvouaemldbq",
      "vtviofwbnalsghox", "ynmefegniqptwaqp", "ixzomtnoisuirdbg",
      "gnakunqpygspsgxj", "qiinftwmjxdgksnh"
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, stringList)

    val stringList1 = jsonArray.parseList<String>()
    val stringList2 = jsonArray.parseList<String>(jsonContext)
    val stringList3 = jsonArray.parseMutableList<String>()
    val stringList4 = jsonArray.parseMutableList<String>(jsonContext)

    for (i in 0 until jsonArray.size()) {
      Assertions.assertEquals(stringList[i], stringList1[i])
      Assertions.assertEquals(stringList1[i], stringList2[i])
      Assertions.assertEquals(stringList2[i], stringList3[i])
      Assertions.assertEquals(stringList3[i], stringList4[i])
    }
  }

  @Test
  fun test_parseSet_parseMutableSet() {
    val stringSet: Set<String> = setOf(
      "vqzxeevwcboswvzv", "qesigpocbptcesea", "pwpxaqwpxdmkkxsj",
      "tztzsifwbdcqmgbg", "fuwkhpsxclqklsew", "jhbcptnhzajghrqw",
      "eebmykfybtipjyck", "kbudqwucdiluswnx", "tbsxebhvkhhtscah",
      "gpdhgrcvqqyxzkxf", "xdurjnroxxwgqduf", "jyjfkxeautxitlcf",
      "hvnuypfxvqlpbgom", "yckfjwkazxaedsum", "whboaazsbowhwzes",
      "vakxxkwjvvblnfkd", "rmqarppbrescpiig", "xkkwmsyipkyjmdgt",
      "dsmmohrmdmlzovfp", "azivdgcgbkrhtaen", "bjqfwvcnhlkpmwfo",
      "gthwdlnfvihgobin", "olaqpqqmrpyaaokg", "fmgozwfvuscuixad",
      "fufnobbnsnngeura", "pyziwqwewinukjma", "feiiywvouaemldbq",
      "vtviofwbnalsghox", "ynmefegniqptwaqp", "ixzomtnoisuirdbg",
      "gnakunqpygspsgxj", "qiinftwmjxdgksnh"
    )

    val jsonContext = JsonContext()
    val jsonArray = JsonArray.fromObject(jsonContext, stringSet)

    val stringSet1 = jsonArray.parseSet<String>()
    val stringSet2 = jsonArray.parseSet<String>(jsonContext)
    val stringSet3 = jsonArray.parseMutableSet<String>()
    val stringSet4 = jsonArray.parseMutableSet<String>(jsonContext)

    val iterator = stringSet.iterator()
    val iterator1 = stringSet1.iterator()
    val iterator2 = stringSet2.iterator()
    val iterator3 = stringSet3.iterator()
    val iterator4 = stringSet4.iterator()

    for (i in 0 until jsonArray.size()) {
      Assertions.assertTrue(iterator.hasNext())
      Assertions.assertTrue(iterator1.hasNext())
      Assertions.assertTrue(iterator2.hasNext())
      Assertions.assertTrue(iterator3.hasNext())
      Assertions.assertTrue(iterator4.hasNext())
      val next = iterator.next()
      val next1 = iterator1.next()
      val next2 = iterator2.next()
      val next3 = iterator3.next()
      val next4 = iterator4.next()
      Assertions.assertEquals(next, next1)
      Assertions.assertEquals(next1, next2)
      Assertions.assertEquals(next2, next3)
      Assertions.assertEquals(next3, next4)
    }
  }
}
